package org.wk.upms.service;

import com.google.common.base.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.wk.core.common.view.PageVo;
import org.wk.upms.dao.RoleDao;
import org.wk.upms.dao.RoleDeptDao;
import org.wk.upms.dao.RoleResourceDao;
import org.wk.upms.domain.RoleDeptEntity;
import org.wk.upms.domain.RoleEntity;
import org.wk.upms.domain.RoleResourceEntity;
import org.wk.upms.view.RoleVo;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class RoleServiceImpl implements RoleService{
    @Autowired
    private RoleDao roleDao;

    @Autowired
    private RoleDeptDao roleDeptDao;

    @Autowired
    private RoleResourceDao roleResourceDao;

    @Override
    public PageVo queryPage(Map<String, Object> params) {
        String roleName = (String)params.get("roleName");
        String temp = (String)params.get("page");
        Integer pageNo = temp==null?0:Integer.parseInt(temp)-1;
        temp = (String) params.get("limit");
        Integer pageSize = temp==null?10:Integer.parseInt(temp);

        //Page<RoleEntity> page = roleDao.findAll(PageRequest.of(pageNo,pageSize,new Sort(Sort.Direction.ASC,"sortNo")));
        Page<RoleEntity> page = roleDao.findAll(new Specification<RoleEntity>() {
            @Override
            public Predicate toPredicate(Root<RoleEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<Predicate>();
                if(!Strings.isNullOrEmpty(roleName)){
                    list.add(criteriaBuilder.like(root.get("roleName").as(String.class), "%"+roleName+"%"));
                }
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            }
        }, PageRequest.of(pageNo,pageSize,new Sort(Sort.Direction.DESC,"sortNo")));

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<RoleVo> roleVos = new ArrayList<>();
        for(RoleEntity roleEntity : page.getContent()){
            RoleVo roleVo = new RoleVo();
            BeanUtils.copyProperties(roleEntity,roleVo);
            roleVo.setRoleId(roleEntity.getId());
            roleVo.setCreateTime(sdf.format(roleEntity.getCreateTime()));
            roleVos.add(roleVo);
        }
        PageVo pageVo = new PageVo<RoleVo>();
        pageVo.setTotal(page.getTotalElements());
        pageVo.setPageNo(++pageNo);
        pageVo.setPageSize(pageSize);
        pageVo.setResult(roleVos);
        pageVo.setTotalPages(page.getTotalPages());
        return pageVo;
    }

    @Override
    public List<RoleVo> selectList(Object o) {
        List<RoleEntity> roleEntities = roleDao.findAll();
        List<RoleVo> roleVos = new ArrayList<>();

        if (roleEntities!=null && !roleEntities.isEmpty()) {
            for (RoleEntity roleEntity:roleEntities) {
                RoleVo roleVo = new RoleVo();
                BeanUtils.copyProperties(roleEntity, roleVo);
                roleVo.setRoleId(roleEntity.getId());
                roleVos.add(roleVo);
            }
        }
        return roleVos;
    }

    @Override
    public RoleVo selectById(String roleId) {
        RoleEntity roleEntity = roleDao.findById(roleId).get();
        RoleVo roleVo = new RoleVo();
        BeanUtils.copyProperties(roleEntity, roleVo);
        roleVo.setRoleId(roleEntity.getId());
        return roleVo;
    }

    @Transactional
    @Override
    public void save(RoleVo role) {
        RoleEntity roleEntity = new RoleEntity();
        BeanUtils.copyProperties(role,roleEntity);
        roleEntity = roleDao.save(roleEntity);
        String roleId = roleEntity.getId();
        //处理数据权限
        List<String> deptIds = role.getDeptIds();
        List<RoleDeptEntity> roleDeptEntities = new ArrayList<>();
        for (String deptId:deptIds) {
            RoleDeptEntity roleDeptEntity = new RoleDeptEntity();
            roleDeptEntity.setRoleId(roleId);
            roleDeptEntity.setDeptId(deptId);
            roleDeptEntities.add(roleDeptEntity);
        }
        roleDeptDao.saveBatch(roleDeptEntities);
        //处理功能权限
        List<String> menuIds = role.getMenuIds();
        List<RoleResourceEntity> roleResourceEntities = new ArrayList<>();
        for (String menuId:menuIds) {
            RoleResourceEntity roleResourceEntity = new RoleResourceEntity();
            roleResourceEntity.setRoleId(roleId);
            roleResourceEntity.setResourceId(menuId);
            roleResourceEntities.add(roleResourceEntity);
        }
        roleResourceDao.saveBatch(roleResourceEntities);

    }

    @Transactional
    @Override
    public void update(RoleVo role) {
        String roleId = role.getRoleId();
        RoleEntity roleEntity =  roleDao.findById(roleId).get();
        BeanUtils.copyProperties(role,roleEntity);
        roleDao.update(roleEntity);

        //处理数据权限
        List<String> deptIds = role.getDeptIds();
        roleDeptDao.deleteByRoleId(roleId);
        List<RoleDeptEntity> roleDeptEntities = new ArrayList<>();
        for (String deptId:deptIds) {
            RoleDeptEntity roleDeptEntity = new RoleDeptEntity();
            roleDeptEntity.setRoleId(roleId);
            roleDeptEntity.setDeptId(deptId);
            roleDeptEntities.add(roleDeptEntity);
        }
        roleDeptDao.saveBatch(roleDeptEntities);

        //处理功能权限
        List<String> menuIds = role.getMenuIds();
        roleResourceDao.deleteByRoleId(roleId);
        List<RoleResourceEntity> roleResourceEntities = new ArrayList<>();
        for (String menuId:menuIds) {
            RoleResourceEntity roleResourceEntity = new RoleResourceEntity();
            roleResourceEntity.setRoleId(roleId);
            roleResourceEntity.setResourceId(menuId);
            roleResourceEntities.add(roleResourceEntity);
        }
        roleResourceDao.saveBatch(roleResourceEntities);

    }

    @Transactional
    @Override
    public void deleteBatch(String[] roleIds) {
        roleDao.deleteByIdIn(roleIds);
        roleDeptDao.deleteByRoleIdIn(roleIds);
        roleResourceDao.deleteByRoleIdIn(roleIds);
    }
}
